﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Windows;


namespace BDSim
{
    public class SpaceSegmentDataProvider : BDSimDataProvider
    {
        private SpaceSegment _Parent;

        /// <summary>
        /// 该数据模型的父级
        /// </summary>
        public SpaceSegment Parent
        {
            get { return _Parent; }
            set { _Parent = value; }
        }

        #region 命令定义

        /// <summary>
        /// 新建星座
        /// </summary>
        MenuCommand AddConstellationCmd = new MenuCommand();

        /// <summary>
        /// 新建北斗星座
        /// </summary>
        MenuCommand AddBDCmd = new MenuCommand();

        /// <summary>
        /// 新建GPS星座
        /// </summary>
        MenuCommand AddGPSCmd = new MenuCommand();

        /// <summary>
        /// 新建GLONASS星座
        /// </summary>
        MenuCommand AddGLONASSCmd = new MenuCommand();

        /// <summary>
        /// 新建GALILEO星座
        /// </summary>
        MenuCommand AddGALILEOCmd = new MenuCommand();
        
        /// <summary>
        /// 新建其它星座
        /// </summary>
        MenuCommand AddDefinedCmd = new MenuCommand();


        /// <summary>
        /// 导入星座
        /// </summary>
        MenuCommand ImportConstellationCmd = new MenuCommand();


        /// <summary>
        /// 从Sp3文件导入星座
        /// </summary>
        MenuCommand ImportFromSp3Cmd = new MenuCommand();

        /// <summary>
        /// 从导航电文中导入星座
        /// </summary>
        MenuCommand ImportFromNavMsgCmd = new MenuCommand();

        /// <summary>
        /// 导入已有星座
        /// </summary>
        MenuCommand ImportFromCSTCmd = new MenuCommand();

        /// <summary>
        /// 导入北斗示例星座
        /// </summary>
        MenuCommand ImportBDConstCmd = new MenuCommand();

        /// <summary>
        /// 导入GPS示例星座
        /// </summary>
        MenuCommand ImportGPSConstCmd = new MenuCommand();

        /// <summary>
        /// 导入GLONASS示例星座
        /// </summary>
        MenuCommand ImportGLONASSConstCmd = new MenuCommand();

        /// <summary>
        /// 导入Galileo示例星座
        /// </summary>
        MenuCommand ImportGalileoConstCmd = new MenuCommand();

        /// <summary>
        /// 导入自定义星座
        /// </summary>
        MenuCommand ImportUserConstCmd = new MenuCommand();

        #endregion

        #region 命令集合初始化

        public override void DefineCommand()
        {
            
            AddConstellationCmd.Header = "新建星座";
            AddConstellationCmd.DefineExcuteCommand(AddConstellationFun_Execute, AddConstellationFun_CanExecute);
            MenuCommandList.Add(AddConstellationCmd); 
            
            ImportFromSp3Cmd.Header = "从Sp3文件导入星座";
            ImportFromSp3Cmd.DefineExcuteCommand(ImportFromSp3Fun_Execute, OpenConstellationFun_CanExecute);
            ImportConstellationCmd.SubMenuCommandList.Add(ImportFromSp3Cmd);

            ImportFromNavMsgCmd.Header = "从导航电文导入星座";
            ImportFromNavMsgCmd.DefineExcuteCommand(ImportFromNavMsgFun_Execute, OpenConstellationFun_CanExecute);
            ImportConstellationCmd.SubMenuCommandList.Add(ImportFromNavMsgCmd);

            ImportBDConstCmd.Header = "BD";
            ImportBDConstCmd.DefineExcuteCommand(ImportFromCSTFun, OpenConstellationFun_CanExecute);
            ImportFromCSTCmd.SubMenuCommandList.Add(ImportBDConstCmd);

            ImportGPSConstCmd.Header = "GPS";
            ImportGPSConstCmd.DefineExcuteCommand(ImportFromCSTFun, OpenConstellationFun_CanExecute);
            ImportFromCSTCmd.SubMenuCommandList.Add(ImportGPSConstCmd);

            ImportGLONASSConstCmd.Header = "GLONASS";
            ImportGLONASSConstCmd.DefineExcuteCommand(ImportFromCSTFun, OpenConstellationFun_CanExecute);
            ImportFromCSTCmd.SubMenuCommandList.Add(ImportGLONASSConstCmd);

            ImportGalileoConstCmd.Header = "Galileo";
            ImportGalileoConstCmd.DefineExcuteCommand(ImportFromCSTFun, OpenConstellationFun_CanExecute);
            ImportFromCSTCmd.SubMenuCommandList.Add(ImportGalileoConstCmd);

            ImportUserConstCmd.Header = "自定义星座";
            ImportUserConstCmd.DefineExcuteCommand(OpenConstellationFun_Execute, OpenConstellationFun_CanExecute);
            ImportFromCSTCmd.SubMenuCommandList.Add(ImportUserConstCmd);

            ImportFromCSTCmd.Header = "导入已有星座";
            ImportConstellationCmd.SubMenuCommandList.Add(ImportFromCSTCmd);

            ImportConstellationCmd.Header = "导入星座";
            MenuCommandList.Add(ImportConstellationCmd);         

            MenuCommand ClearConstellationCmd = new MenuCommand();
            ClearConstellationCmd.Header = "清空";
            ClearConstellationCmd.DefineExcuteCommand(ClearConstellationFun_Execute, ClearConstellationFun_CanExecute);
            MenuCommandList.Add(ClearConstellationCmd);
        }

        #endregion

        #region 命令执行内容

        #region 新建星座
        /// <summary>
        /// 新建星座的执行方法
        /// </summary>
        void AddConstellationFun_Execute(object param)
        {
            Constellation Con = new Constellation();
            Con.ConstellationFeature.ConstellationType = EConstellationType.BD;
            Con.ConstellationFeature.NavMsgUpdateFrequency = 3600;
            Con.Parent = this.Parent;
            Con.Name = "Constellation" + (Parent.ConstellationList.Count + 1).ToString();
            Con.Type = ESpaceType.Constellation;
            Parent.ConstellationList.Add(Con);
        }
        bool AddConstellationFun_CanExecute(object param)
        {
            bool flag = false;
            if (BDSimObject.GlobalStatus == ESimStatus.UnInited || BDSimObject.GlobalStatus == ESimStatus.End)
            {
                flag = true;
            }
            return flag;
        }
        #endregion

        #region 导入星座

        /// <summary>
        /// 从Sp3文件导入星座的执行方法
        /// </summary>
        void ImportFromSp3Fun_Execute(object param)
        {
            LoadSp3DataWnd loadSp3Wnd = new LoadSp3DataWnd();
            if (loadSp3Wnd.ShowDialog() == true)
            {
                ///先新建星座，判断星座类型
                Constellation Con = new Constellation();
                Con.ConstellationFeature.ConstellationType = EConstellationType.BD;
                Con.ConstellationFeature.NavMsgUpdateFrequency = 3600;
                Con.Parent = this.Parent;
                Con.Name = "Constellation" + (Parent.ConstellationList.Count + 1).ToString();
                if (loadSp3Wnd.head.SysType=='G')
                {
                     Con.ConstellationFeature.ConstellationType = EConstellationType.GPS;
                }
                if (loadSp3Wnd.head.SysType=='R')
                {
                     Con.ConstellationFeature.ConstellationType = EConstellationType.GLONASS;
                }
                Con.Type = ESpaceType.Constellation;
                Parent.ConstellationList.Add(Con);

                int satindex = 0;
                foreach (var item in loadSp3Wnd.SelectSP3Data)
                {
                    if (item.IsChecked)
                    {
                        Satellite newSat = new Satellite();
                        newSat.Name = loadSp3Wnd.head.SysType + (item.PRN.ToString()).PadLeft(2,'0');
                        newSat.Orbit.InitPV_ECI = loadSp3Wnd.SatInitPV_ECI[satindex];
                        newSat.Parent = Parent.ConstellationList[Parent.ConstellationList.Count - 1];
                        Parent.ConstellationList[Parent.ConstellationList.Count - 1].SatelliteCollection.Add(newSat);
                        satindex++;
                    }

                }
                if (loadSp3Wnd.IsUseEpoch.IsChecked == true)
                {                    
                    UTCTime temptime = loadSp3Wnd.SelectEpoch;
                    TimeSpaceDll.CAL2UTC(out temptime, 1);
                    Parent.Parent.StartTime = temptime.ToUTCTimeClass();
                    Parent.Parent.EpochTime = temptime.ToUTCTimeClass();
                    temptime.JD = temptime.JD + 1;
                    TimeSpaceDll.CAL2UTC(out temptime, 2);
                    Parent.Parent.EndTime = temptime.ToUTCTimeClass();
                    Parent.Parent.EnvironmentSegmentInit();
                }
                else
                {
                    Parent.Parent.StartTime = BDSimObject.GlobalStartTime.ToUTCTimeClass();
                    Parent.Parent.EpochTime = BDSimObject.GlobalStartTime.ToUTCTimeClass();
                    Parent.Parent.EndTime = BDSimObject.GlobalEndTime.ToUTCTimeClass();
                    Parent.Parent.EnvironmentSegmentInit();
                }
            }
        }

        /// <summary>
        /// 从导航电文导入星座的执行方法
        /// </summary>
        void ImportFromNavMsgFun_Execute(object param)
        {
            LoadNavMsgDataWnd loadNav = new LoadNavMsgDataWnd();
            if (loadNav.ShowDialog() == true)
            {
               // AddConstellationFun_Execute(param);
                Dictionary<char, Constellation> NavMsgCon = new Dictionary<char, Constellation>();
                foreach (var item in loadNav.NavMsgPVList[loadNav.SelectedIndex])
                {
                    foreach (var itemdata in loadNav.SelectNavData)
                    {
                        if (itemdata.PRN == item.Key && itemdata.IsChecked == true)
                        {
                            Satellite newSat = new Satellite();
                            newSat.Name = item.Value.SysType + item.Key.ToString();
                            newSat.Clock.Clk_b0 = item.Value.a0;
                            newSat.Clock.Clk_d0 = item.Value.a1;
                            newSat.Clock.Clk_r0 = item.Value.a2;
                            newSat.Orbit.InitPV_ECI = item.Value.SatPV.ConvertToClass();

                            ///根据卫星类型判断星座类型
                            if (item.Value.SysType == 'G')
                            {
                                if (!NavMsgCon.Keys.Contains(item.Value.SysType))
                                {
                                    Constellation Con = new Constellation();
                                    Con.ConstellationFeature.ConstellationType = EConstellationType.GPS;
                                    Con.ConstellationFeature.NavMsgUpdateFrequency = 3600;
                                    Con.Parent = this.Parent;
                                    Con.Name = "Constellation" + (Parent.ConstellationList.Count + 1).ToString();
                                    Con.Type = ESpaceType.Constellation;
                                    NavMsgCon.Add('G', Con);                              
                                }

                           }
                            if (item.Value.SysType == 'C')
                            {
                                if (!NavMsgCon.Keys.Contains(item.Value.SysType))
                                {
                                    Constellation Con = new Constellation();
                                    Con.ConstellationFeature.ConstellationType = EConstellationType.BD;
                                    Con.ConstellationFeature.NavMsgUpdateFrequency = 3600;
                                    Con.Parent = this.Parent;
                                    Con.Name = "Constellation" + (Parent.ConstellationList.Count + 1).ToString();
                                    Con.Type = ESpaceType.Constellation;
                                    NavMsgCon.Add('C', Con);
                                }
                            }
                            newSat.Parent = NavMsgCon[item.Value.SysType];
                            NavMsgCon[item.Value.SysType].SatelliteCollection.Add(newSat);

                        }
                    }
                }

                foreach (var item in NavMsgCon.Values)
                {
                    if (item.SatelliteCollection.Count>0)
                    {
                        Parent.ConstellationList.Add(item);
                    }
                }

                loadNav.LoadState.Text = "导入完毕";
                if (loadNav.IsUseDocTime.IsChecked == true)
                {
                    UTCTime temptime = loadNav.NavMsgReportList[loadNav.SelectedIndex].Epoch;
                    TimeSpaceDll.CAL2UTC(out temptime, 1);
                    Parent.Parent.StartTime = temptime.ToUTCTimeClass();
                    Parent.Parent.EpochTime = temptime.ToUTCTimeClass();
                    temptime.JD = temptime.JD + 1;
                    TimeSpaceDll.CAL2UTC(out temptime, 2);
                    Parent.Parent.EndTime = temptime.ToUTCTimeClass();                    
                    Parent.Parent.EnvironmentSegmentInit();
                }
                else
                {
                    Parent.Parent.StartTime = BDSimObject.GlobalStartTime.ToUTCTimeClass();
                    Parent.Parent.EpochTime = BDSimObject.GlobalStartTime.ToUTCTimeClass();
                    Parent.Parent.EndTime = BDSimObject.GlobalEndTime.ToUTCTimeClass();
                    Parent.Parent.EnvironmentSegmentInit();
                }
            }
        }

        /// <summary>
        /// 从已保存的星座文件中导入星座的执行方法
        /// </summary>
        void ImportFromCSTFun(object param)
        {
            try
            {
                LoadConstellationFile(@"ConstellationFiles\" + param.ToString() + ".cst");
            }
            catch (Exception)
            {
                BDSimObject.DlgReportPropertyInfo( param.ToString() + "文件丢失!");
            }
        }

        /// <summary>
        /// 导入星座的执行方法
        /// </summary>
        void OpenConstellationFun_Execute(object param)
        {            
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "星座文件|*.cst";
            if (ofd.ShowDialog() == true)
            {
                try
                {
                    LoadConstellationFile(ofd.FileName);
                   // BDSimObject.DlgReportPropertyInfo("星座文件“" + ofd.FileName + "”打开成功!");
                    MessageBox.Show("星座文件“" + ofd.FileName + "”打开成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception exp)
                {
                    BDSimObject.DlgReportPropertyInfo("星座文件包含非法信息，打开失败!\r\n" + exp.ToString());
                }
                
            }
        }

        /// <summary>
        /// 从文件路径导入星座
        /// </summary>
        /// <param name="fileName"></param>
        private void LoadConstellationFile(string fileName)
        {
            ConstellationXmlFile conData = new ConstellationXmlFile();
            conData = XmlFileOperater<ConstellationXmlFile>.LoadFromFile(fileName);
            foreach (var sat in conData.ConstellationData.SatelliteCollection)
            {
                sat.Orbit.Parent = sat;
                sat.Clock.Parent = sat;
                sat.Parent = conData.ConstellationData;
            }
            conData.ConstellationData.Parent = this.Parent;
            conData.ConstellationData.ConstellationFeature.Parent = conData.ConstellationData;
            if (0==this.Parent.ConstellationList.Count())
            {
                this.Parent.ConstellationList.Add(conData.ConstellationData);
            }
            else
            {
                for (int i = 0; i < this.Parent.ConstellationList.Count(); i++)
                {
                    if (conData.ConstellationData.ConstellationFeature.ConstellationType == this.Parent.ConstellationList[i].ConstellationFeature.ConstellationType)
                    {
                        System.Windows.Forms.MessageBox.Show("已添加了该类型的星座！");
                        return;
                    }
                }
                this.Parent.ConstellationList.Add(conData.ConstellationData);
            }
        }

        bool OpenConstellationFun_CanExecute(object param)
        {
            bool flag = false;
            if (BDSimObject.GlobalStatus == ESimStatus.UnInited || BDSimObject.GlobalStatus == ESimStatus.End)
            {
                flag = true;
            }
            return flag;
        }
        #endregion
        
        #region 清除所有星座
        void ClearConstellationFun_Execute(object param)
        {
            Parent.ConstellationList.Clear();
        }
        bool ClearConstellationFun_CanExecute(object param)
        {
            bool flag = false;
            if (BDSimObject.GlobalStatus == ESimStatus.UnInited || BDSimObject.GlobalStatus == ESimStatus.End)
            {
                flag = true;
            }
            return flag;
        }
        #endregion

        #endregion


    }
}
